package edu.ccut.saturn.studio.database.ui;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.sql.Driver;
import java.util.HashMap;
import java.util.Map;

public class DriverJarUtil extends ClassLoader {

	private static Map<String, ClassLoader> classLoaderCache = new HashMap<String, ClassLoader>();

	private DriverJarUtil() {
	}

	public static Driver loadDriver(String path, String className)
			throws Exception {
		Class<?> clazz = loadDriverClass(path, className);
		if (clazz != null) {
			return (Driver) clazz.newInstance();
		}
		return null;
	}

	public static Class<?> loadDriverClass(String path, String className)
			throws Exception {

		ClassLoader urlclassloader = getURLClassLoader(getFiles(path));

		return loadDriverClass(className, urlclassloader);
	}

	private static File[] getFiles(String path) {
		File file = new File(path);

		if (file.exists()) {
			if (file.isFile()) {
				return new File[] { file };
			}

			if (file.isDirectory()) {
				return file.listFiles();
			}
		}

		return null;
	}

	@SuppressWarnings("unchecked")
	private static Class loadDriverClass(String s, ClassLoader classloader)
			throws ClassNotFoundException {
		Class class1 = classloader.loadClass(s);
		return java.sql.Driver.class.isAssignableFrom(class1) ? class1 : null;
	}

	private static ClassLoader getURLClassLoader(File[] files)
			throws MalformedURLException {

		String path = getFilePath(files);

		ClassLoader urlclassloader = classLoaderCache.get(path);

		if (urlclassloader == null && files != null) {
			URL urls[] = new URL[files.length];

			for (int i = 0; i < urls.length; i++) {
				urls[i] = files[i].toURL();
			}

			urlclassloader = new URLClassLoader(urls);

			if (urlclassloader != null) {
				classLoaderCache.put(path, urlclassloader);
			}
		}

		return urlclassloader;
	}

	private static String getFilePath(File file[]) {
		StringBuffer stringbuffer = new StringBuffer();

		if (file != null) {
			int length = file.length;

			for (int i = 0; i < length; i++) {
				stringbuffer.append(file[i].getAbsolutePath());

				if (i < length - 1) {
					stringbuffer.append(File.pathSeparator);
				}
			}
		}

		return stringbuffer.toString();
	}
}